package com.partsoft.dits.log;

import java.io.IOException;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;

import org.apache.log4j.Level;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.ContextStoppedEvent;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import com.partsoft.dits.ConfigurableBean;
import com.partsoft.dits.ContextConfigurableBean;
import com.partsoft.dits.DescriptorDepends;
import com.partsoft.dits.DescriptorRegistry;
import com.partsoft.dits.EdgeDescriptor;
import com.partsoft.dits.dsm.DataSourceDescriptor;
import com.partsoft.dits.dsm.DataSourceFactory;

/**
 * Log4J日志整合上下文配置器
 */
public class ContextDataSourceLog4jAdhesives extends
		AbstractDataSourceLog4jAdhesives implements ConfigurableBean,
		LogResolver, LogManager, LogAdapter, 
		ApplicationContextAware, ApplicationListener<ApplicationEvent>, 
		DescriptorDepends<EdgeDescriptor> {
	
	public static final String LOG_CONFIG_BEANID = "ditsLogConfig";
	
	private LogConfig logConfig;
	
	private ContextReferDataSourceLogManager logManager;
	
	private BaseDataSourceLogAdapter logAdapter;
	
	private String namespace;
	
	private boolean inited = false;
	
	private boolean logDataSourceConfigured = false;
	
	protected ApplicationContext ownerContext;

	private DescriptorRegistry<DataSourceDescriptor> dataSourceRegistry;
	
	private DataSourceFactory dataSourceFactory;
	
	protected final ContextConfigurableBean dsLog4jConfigDelegate = new ContextConfigurableBean() {
		@Override
		protected void unLoadContextConfiguredBeans() {}
		
		@Override
		protected void loadContextConfiguredBeans(ConfigurableApplicationContext ctx) {
			if (ctx.containsBean(LOG_CONFIG_BEANID)) {
				try {
					logConfig = ctx.getBean(LOG_CONFIG_BEANID, LogConfig.class);
				} catch (Exception e) {
					logConfig = null;
				}
			}
		}
	};
	
	public ContextDataSourceLog4jAdhesives() {}
	
	public ContextDataSourceLog4jAdhesives(String contextConfigLocation) {
		dsLog4jConfigDelegate.setContextProfileLocation(contextConfigLocation);
	}
	
	public ContextDataSourceLog4jAdhesives(String contextConfigLocation, boolean createNoExists) {
		dsLog4jConfigDelegate.setContextProfileLocation(contextConfigLocation);
		dsLog4jConfigDelegate.setCreateProfileNoExists(createNoExists);
	}
	
	public boolean isProfileCanBeWrite() {
		return dsLog4jConfigDelegate.isProfileCanBeWrite();
	}

	public void setProfileCanBeWrite(boolean profileCanBeWrite) {
		dsLog4jConfigDelegate.setProfileCanBeWrite(profileCanBeWrite);
	}

	public boolean isCreateProfileNoExists() {
		return dsLog4jConfigDelegate.isCreateProfileNoExists();
	}

	public void setCreateProfileNoExists(boolean createNoExists) {
		dsLog4jConfigDelegate.setCreateProfileNoExists(createNoExists);
	}

	public String getContextProfileLocation() {
		return dsLog4jConfigDelegate.getContextProfileLocation();
	}

	public void setContextProfileLocation(String contextConfigLocation) {
		dsLog4jConfigDelegate.setContextProfileLocation(contextConfigLocation);
	}
	
	public String getNamespace() {
		return namespace;
	}

	public void setNamespace(String namespace) {
		this.namespace = namespace;
	}

	public boolean isLogDataSourceConfigured() {
		assertInited();
		return logDataSourceConfigured && super.isLogDataSourceConfigured();
	};
	
	protected void assertInited() {
		Assert.isTrue(inited, "未初始化上下文");
	}

	public String getLogDataSource() {
		assertInited();
		return logConfig.getDataSourceName();
	}
	
	public DescriptorRegistry<DataSourceDescriptor> getDataSourceRegistry() {
		return dataSourceRegistry;
	}

	public void setDataSourceRegistry(DescriptorRegistry<DataSourceDescriptor> dataSourceRegistry) {
		this.dataSourceRegistry = dataSourceRegistry;
	}
	

	public DataSourceFactory getDataSourceFactory() {
		return dataSourceFactory;
	}

	public void setDataSourceFactory(DataSourceFactory dataSourceFactory) {
		this.dataSourceFactory = dataSourceFactory;
	}

	@Override
	protected boolean hasDataSource(String dsName) {
		return getDataSourceRegistry().hasDescriptor(new DataSourceDescriptor(dsName));
	}
	
	@Override
	protected DataSourceDescriptor getDataSourceDescriptor(String dsName) {
		return getDataSourceRegistry().getDescriptor(new DataSourceDescriptor(dsName));
	}
	
	@Override
	protected synchronized void doSetupLogDataSource(String dsName, Level logLevel) throws IOException {
		assertInited();
		super.doSetupLogDataSource(dsName, logLevel);
		dsLog4jConfigDelegate.removeConfiguredBean(LOG_CONFIG_BEANID);
		if (StringUtils.hasText(dsName)) {
			Properties props = new Properties();
			props.setProperty("dataSourceName", dsName);
			props.setProperty("dataSourceLogLevel", logLevel.toString());
			dsLog4jConfigDelegate.appendConfiguredBean(LOG_CONFIG_BEANID, LogConfig.class.getName(), props);
			logConfig = new LogConfig();
			logConfig.setDataSourceName(dsName);
			logConfig.setDataSourceLogLevel(logLevel.toString());
			doSetupLogManager(dsName, logLevel);
			logDataSourceConfigured = true;
		} else {
			logDataSourceConfigured = false;
		}
	}
	
	private synchronized void doSetupLogManager(String dsName, Level logLevel) {
		Assert.hasText(dsName);
		Assert.notNull(logLevel);
		logManager = new ContextReferDataSourceLogManager(getDataSourceFactory(), dsName);
		logManager.setNamespace(getNamespace());
		logManager.initContext();
		if (!logManager.getLogAdapter().isDeployed()) {
			logManager.getLogAdapter().deployTables();
		}
	}
	
	protected void assertLogDataSourceConfigured() {
		Assert.isTrue(isLogDataSourceConfigured(), "未配置数据源运行日志");
	}

	public LogManager getLogManager() {
		assertLogDataSourceConfigured();
		return logManager;
	}
	
	public LogResolver getLogResolver() {
		assertLogDataSourceConfigured();
		return logManager;
	}

	public LogAdapter getLogAdapter() {
		assertLogDataSourceConfigured();
		return logAdapter;
	}
	
	public void finiContext() {
		synchronized (this) {
			dsLog4jConfigDelegate.finiContext();
			logConfig = null;
			logAdapter = null;
			logManager = null;
			inited = false;
		}
	}

	public void initContext() {
		synchronized (this) {
			if (inited) finiContext();
			dsLog4jConfigDelegate.initContext();
			if ((logConfig == null || !StringUtils.hasText(logConfig.getDataSourceName())) && super.isLogDataSourceConfigured()) {
				try {
					super.doSetupLogDataSource(null, null);
				} catch (IOException e) {
					throw new IllegalArgumentException(String.format("移除数据源日志配置时出错: %s", e.getMessage()));
				}
			}
			if (logConfig != null && StringUtils.hasText(logConfig.getDataSourceName())) {
				logManager = new ContextReferDataSourceLogManager(getDataSourceFactory(), logConfig.getDataSourceName());
				if (!super.isLogDataSourceConfigured()) try {
					super.doSetupLogDataSource(logConfig.getDataSourceName(), Level.toLevel(logConfig.getDataSourceLogLevel()));
				} catch (IOException e) {
					throw new IllegalArgumentException(String.format("自动部署数据源日志配置时出错: %s", e.getMessage()));
				}
				this.doSetupLogManager(logConfig.getDataSourceName(), Level.toLevel(logConfig.getDataSourceLogLevel()));
				logDataSourceConfigured = true;
			}
			inited = true;
		}
	}

	
	//Implements LogResolver
	public boolean isImplemented() {
		return this.logDataSourceConfigured;
	}
	

	public int getLogCount() {
		return getLogResolver().getLogCount();
	}

	public List<LogEntity> getLogs() {
		return getLogResolver().getLogs();
	}

	public List<LogEntity> getLogs(int from, int count) {
		return getLogResolver().getLogs(from, count);
	}

	public int getLogCount(String queryString) {
		return getLogResolver().getLogCount(queryString);
	}

	public List<LogEntity> getLogs(String queryString) {
		return getLogResolver().getLogs(queryString);
	}

	public List<LogEntity> getLogs(String queryString, int from, int count) {
		return getLogResolver().getLogs(queryString, from, count);
	}

	public int getLogCount(LogLevel logLevel) {
		return getLogResolver().getLogCount(logLevel);
	}

	public List<LogEntity> getLogs(LogLevel logLevel) {
		return getLogResolver().getLogs(logLevel);
	}

	public List<LogEntity> getLogs(LogLevel logLevel, int from, int count) {
		return getLogResolver().getLogs(logLevel, from, count);
	}

	public int getLogCount(LogLevel logLevel, String queryString) {
		return getLogResolver().getLogCount(logLevel, queryString);
	}

	public List<LogEntity> getLogs(LogLevel logLevel, String queryString) {
		return getLogResolver().getLogs(logLevel, queryString);
	}

	public List<LogEntity> getLogs(LogLevel logLevel, String queryString,
			int from, int count) {
		return getLogResolver().getLogs(logLevel, queryString, from, count);
	}

	public int getLogCount(LogType logType, LogLevel logLevel,
			String queryString) {
		return getLogResolver().getLogCount(logType, logLevel, queryString);
	}

	public List<LogEntity> getLogs(LogType logType, LogLevel logLevel,
			String queryString) {
		return getLogResolver().getLogs(logType, logLevel, queryString);
	}

	public int getLogCount(EdgeDescriptor descriptor) {
		return getLogResolver().getLogCount(descriptor);
	}

	public List<LogEntity> getLogs(EdgeDescriptor descriptor) {
		return getLogResolver().getLogs(descriptor);
	}

	public List<LogEntity> getLogs(EdgeDescriptor descriptor, int from,
			int count) {
		return getLogResolver().getLogs(descriptor, from, count);
	}

	public int getLogCount(EdgeDescriptor descriptor, LogLevel logLevel) {
		return getLogResolver().getLogCount(descriptor, logLevel);
	}

	public List<LogEntity> getLogs(EdgeDescriptor descriptor, LogLevel logLevel) {
		return getLogResolver().getLogs(descriptor, logLevel);
	}

	public List<LogEntity> getLogs(EdgeDescriptor descriptor,
			LogLevel logLevel, int from, int count) {
		return getLogResolver().getLogs(descriptor, logLevel, from, count);
	}

	public int getLogCount(EdgeDescriptor descriptor, String queryString) {
		return getLogResolver().getLogCount(descriptor, queryString);
	}

	public List<LogEntity> getLogs(EdgeDescriptor descriptor, String queryString) {
		return getLogResolver().getLogs(descriptor, queryString);
	}

	public int getLogCount(EdgeDescriptor descriptor, LogType logType) {
		return getLogResolver().getLogCount(descriptor, logType);
	}

	public List<LogEntity> getLogs(EdgeDescriptor descriptor, LogType logType) {
		return getLogResolver().getLogs(descriptor, logType);
	}

	public int getLogCount(EdgeDescriptor descriptor, LogType logType,
			LogLevel logLevel, String queryString) {
		return getLogResolver().getLogCount(descriptor, logType, logLevel,
				queryString);
	}

	public int getLogCount(EdgeDescriptor descriptor, LogType logType,
			LogLevel logLevel, String queryString, Date beginDay, Date endDay) {
		return getLogResolver().getLogCount(descriptor, logType, logLevel,
				queryString, beginDay, endDay);
	}

	public List<LogEntity> getLogs(EdgeDescriptor descriptor, LogType logType,
			LogLevel logLevel, String queryString) {
		return getLogResolver().getLogs(descriptor, logType, logLevel, queryString);
	}

	public List<LogEntity> getLogs(EdgeDescriptor descriptor,
			String queryString, int from, int count) {
		return getLogResolver().getLogs(descriptor, queryString, from, count);
	}

	public List<LogEntity> getLogs(EdgeDescriptor descriptor, LogType logLevel,
			int from, int count) {
		return getLogResolver().getLogs(descriptor, logLevel, from, count);
	}

	public List<LogEntity> getLogs(EdgeDescriptor descriptor, LogType logType,
			LogLevel logLevel, String queryString, int from, int count) {
		return getLogResolver().getLogs(descriptor, logType, logLevel, queryString,
				from, count);
	}

	public List<LogEntity> getLogs(EdgeDescriptor descriptor, LogType logType,
			LogLevel logLevel, String queryString, Date beginDay, Date endDay,
			int from, int count) {
		return getLogResolver().getLogs(descriptor, logType, logLevel, queryString,
				beginDay, endDay, from, count);
	}

	//Implements LogManager
	public void removeLog(LogEntity logEntity) {
		getLogManager().removeLog(logEntity);
	}

	public void removeLog(EdgeDescriptor descriptor) {
		getLogManager().removeLog(descriptor);
	}

	public void removeLog(LogLevel level) {
		getLogManager().removeLog(level);
	}

	public void removeLog(EdgeDescriptor descriptor, LogLevel level) {
		getLogManager().removeLog(descriptor, level);
	}

	public void removeLog(LogLevel level, String queryString) {
		getLogManager().removeLog(level, queryString);
	}

	public void removeLog(EdgeDescriptor descriptor, LogLevel level,
			String queryString) {
		getLogManager().removeLog(descriptor, level, queryString);
	}

	public void removeLog(LogType type) {
		getLogManager().removeLog(type);
	}

	public void removeLog(EdgeDescriptor descriptor, LogType type) {
		getLogManager().removeLog(descriptor, type);
	}

	public void removeLog(LogType type, String queryString) {
		getLogManager().removeLog(type, queryString);
	}

	public void removeLog(EdgeDescriptor descriptor, LogType type,
			String queryString) {
		getLogManager().removeLog(descriptor, type, queryString);
	}

	public void removeLog(LogType logType, LogLevel level) {
		getLogManager().removeLog(logType, level);
	}

	public void removeLog(LogType logType, LogLevel level, String queryString) {
		getLogManager().removeLog(logType, level, queryString);
	}

	public void removeLog(EdgeDescriptor descriptor, LogType logType,
			LogLevel level, String queryString) {
		getLogManager().removeLog(descriptor, logType, level, queryString);
	}

	public void removeLogBefore(Date beforeDate) {
		getLogManager().removeLogBefore(beforeDate);
	}

	public void removeLogBefore(EdgeDescriptor descriptor, Date beforeDate) {
		getLogManager().removeLogBefore(descriptor, beforeDate);
	}

	public void removeLogBefore(Date beforeDate, String queryString) {
		getLogManager().removeLogBefore(beforeDate, queryString);
	}

	public void removeLogBefore(EdgeDescriptor descriptor, Date beforeDate,
			String queryString) {
		getLogManager().removeLogBefore(descriptor, beforeDate, queryString);
	}

	public void removeLogBefore(LogType type, Date beforeDate) {
		getLogManager().removeLogBefore(type, beforeDate);
	}

	public void removeLogBefore(EdgeDescriptor descriptor, LogType type,
			Date beforeDate) {
		getLogManager().removeLogBefore(descriptor, type, beforeDate);
	}

	public void removeLogBefore(LogType type, Date beforeDate,
			String queryString) {
		getLogManager().removeLogBefore(type, beforeDate, queryString);
	}

	public void removeLogBefore(EdgeDescriptor descriptor, LogType type,
			Date beforeDate, String queryString) {
		getLogManager().removeLogBefore(descriptor, type, beforeDate, queryString);
	}

	public void removeLogBefore(LogType type, LogLevel level, Date beforeDate) {
		getLogManager().removeLogBefore(type, level, beforeDate);
	}

	public void removeLogBefore(EdgeDescriptor descriptor, LogType type,
			LogLevel level, Date beforeDate) {
		getLogManager().removeLogBefore(descriptor, type, level, beforeDate);
	}

	public void removeLogBefore(LogType type, LogLevel level, Date beforeDate,
			String queryString) {
		getLogManager().removeLogBefore(type, level, beforeDate, queryString);
	}

	public void removeLogBefore(EdgeDescriptor descriptor, LogType type,
			LogLevel level, Date beforeDate, String queryString) {
		getLogManager().removeLogBefore(descriptor, type, level, beforeDate,
				queryString);
	}

	public void removeLogBefore(LogLevel level, Date beforeDate) {
		getLogManager().removeLogBefore(level, beforeDate);
	}

	public void removeLogBefore(EdgeDescriptor descriptor, LogLevel level,
			Date beforeDate) {
		getLogManager().removeLogBefore(descriptor, level, beforeDate);
	}

	public void removeLogBefore(LogLevel level, Date beforeDate,
			String queryString) {
		getLogManager().removeLogBefore(level, beforeDate, queryString);
	}

	public void removeLogBefore(EdgeDescriptor descriptor, LogLevel level,
			Date beforeDate, String queryString) {
		getLogManager().removeLogBefore(descriptor, level, beforeDate, queryString);
	}

	public void removeLogAfter(Date afterDate) {
		getLogManager().removeLogAfter(afterDate);
	}

	public void removeLogAfter(EdgeDescriptor descriptor, Date afterDate) {
		getLogManager().removeLogAfter(descriptor, afterDate);
	}

	public void removeLogAfter(Date afterDate, String queryString) {
		getLogManager().removeLogAfter(afterDate, queryString);
	}

	public void removeLogAfter(EdgeDescriptor descriptor, Date afterDate,
			String queryString) {
		getLogManager().removeLogAfter(descriptor, afterDate, queryString);
	}

	public void removeLogAfter(LogType type, Date afterDate) {
		getLogManager().removeLogAfter(type, afterDate);
	}

	public void removeLogAfter(EdgeDescriptor descriptor, LogType type,
			Date afterDate) {
		getLogManager().removeLogAfter(descriptor, type, afterDate);
	}

	public void removeLogAfter(LogType type, Date afterDate, String queryString) {
		getLogManager().removeLogAfter(type, afterDate, queryString);
	}

	public void removeLogAfter(EdgeDescriptor descriptor, LogType type,
			Date afterDate, String queryString) {
		getLogManager().removeLogAfter(descriptor, type, afterDate, queryString);
	}

	public void removeLogAfter(LogLevel level, Date afterDate) {
		getLogManager().removeLogAfter(level, afterDate);
	}

	public void removeLogAfter(EdgeDescriptor descriptor, LogLevel level,
			Date afterDate) {
		getLogManager().removeLogAfter(descriptor, level, afterDate);
	}

	public void removeLogAfter(LogLevel level, Date afterDate,
			String queryString) {
		getLogManager().removeLogAfter(level, afterDate, queryString);
	}

	public void removeLogAfter(EdgeDescriptor descriptor, LogLevel level,
			Date afterDate, String queryString) {
		getLogManager().removeLogAfter(descriptor, level, afterDate, queryString);
	}

	public void removeLogAfter(LogType type, LogLevel level, Date afterDate) {
		getLogManager().removeLogAfter(type, level, afterDate);
	}

	public void removeLogAfter(EdgeDescriptor descriptor, LogType type,
			LogLevel level, Date afterDate) {
		getLogManager().removeLogAfter(descriptor, type, level, afterDate);
	}

	public void removeLogAfter(LogType type, LogLevel level, Date afterDate,
			String queryString) {
		getLogManager().removeLogAfter(type, level, afterDate, queryString);
	}

	public void removeLogAfter(EdgeDescriptor descriptor, LogType type,
			LogLevel level, Date afterDate, String queryString) {
		getLogManager().removeLogAfter(descriptor, type, level, afterDate,
				queryString);
	}

	public void removeLogBetween(Date startDate, Date endDate) {
		getLogManager().removeLogBetween(startDate, endDate);
	}

	public void removeLogBetween(EdgeDescriptor descriptor, Date startDate,
			Date endDate) {
		getLogManager().removeLogBetween(descriptor, startDate, endDate);
	}

	public void removeLogBetween(Date startDate, Date endDate,
			String queryString) {
		getLogManager().removeLogBetween(startDate, endDate, queryString);
	}

	public void removeLogBetween(EdgeDescriptor descriptor, Date startDate,
			Date endDate, String queryString) {
		getLogManager().removeLogBetween(descriptor, startDate, endDate, queryString);
	}

	public void removeLogBetween(LogType type, Date startDate, Date endDate) {
		getLogManager().removeLogBetween(type, startDate, endDate);
	}

	public void removeLogBetween(EdgeDescriptor descriptor, LogType type,
			Date startDate, Date endDate) {
		getLogManager().removeLogBetween(descriptor, type, startDate, endDate);
	}

	public void removeLogBetween(LogType type, Date startDate, Date endDate,
			String queryString) {
		getLogManager().removeLogBetween(type, startDate, endDate, queryString);
	}

	public void removeLogBetween(EdgeDescriptor descriptor, LogType type,
			Date startDate, Date endDate, String queryString) {
		getLogManager().removeLogBetween(descriptor, type, startDate, endDate,
				queryString);
	}

	public void removeLogBetween(LogLevel level, Date startDate, Date endDate) {
		getLogManager().removeLogBetween(level, startDate, endDate);
	}

	public void removeLogBetween(EdgeDescriptor descriptor, LogLevel level,
			Date startDate, Date endDate) {
		getLogManager().removeLogBetween(descriptor, level, startDate, endDate);
	}

	public void removeLogBetween(LogLevel level, Date startDate, Date endDate,
			String queryString) {
		getLogManager().removeLogBetween(level, startDate, endDate, queryString);
	}

	public void removeLogBetween(EdgeDescriptor descriptor, LogLevel level,
			Date startDate, Date endDate, String queryString) {
		getLogManager().removeLogBetween(descriptor, level, startDate, endDate,
				queryString);
	}

	public void removeLogBetween(LogType type, LogLevel level, Date startDate,
			Date endDate) {
		getLogManager().removeLogBetween(type, level, startDate, endDate);
	}

	public void removeLogBetween(EdgeDescriptor descriptor, LogType type,
			LogLevel level, Date startDate, Date endDate) {
		getLogManager().removeLogBetween(descriptor, type, level, startDate, endDate);
	}

	public void removeLogBetween(LogType type, LogLevel level, Date startDate,
			Date endDate, String queryString) {
		getLogManager().removeLogBetween(type, level, startDate, endDate, queryString);
	}

	public void removeLogBetween(EdgeDescriptor descriptor, LogType type,
			LogLevel level, Date startDate, Date endDate, String queryString) {
		getLogManager().removeLogBetween(descriptor, type, level, startDate, endDate,
				queryString);
	}
	
	
	public void removeLog(String dclsName, String did) {
		getLogManager().removeLog(dclsName, did);
	}

	public void removeLog(String dclsName, String did, LogLevel level, String queryString) {
		getLogManager().removeLog(dclsName, did, level, queryString);
	}

	public void removeLog(String dclsName, String did, LogType type, String queryString) {
		getLogManager().removeLog(dclsName, did, type, queryString);
	}

	public void removeLogBefore(String dclsName, String did, LogLevel level, Date beforeDate, String queryString) {
		getLogManager().removeLogBefore(dclsName, did, level, beforeDate, queryString);
	}

	public void removeLogAfter(String dclsName, String did, LogType type, LogLevel level, Date afterDate, String queryString) {
		getLogManager().removeLogAfter(dclsName, did, type, level, afterDate, queryString);
	}

	public void removeLogBetween(String dclsName, String did, LogType type, LogLevel level, Date startDate, Date endDate, String queryString) {
		getLogManager().removeLogBetween(dclsName, did, type, level, startDate, endDate, queryString);
	}

	public int getLogCount(String dclsName, String did, LogType logType, LogLevel logLevel, String queryString, Date beginDay, Date endDay) {
		return getLogResolver().getLogCount(dclsName, did, logType, logLevel, queryString, beginDay, endDay);
	}

	public List<LogEntity> getLogs(String dclsName, String did, LogType logType, LogLevel logLevel, String queryString, Date beginDay, Date endDay, int from, int count) {
		return getLogResolver().getLogs(dclsName, did, logType, logLevel, queryString, beginDay, endDay, from, count);
	}

	//Implements LogAdapter
	public void savelog(LogEntity logEntity) {
		getLogAdapter().savelog(logEntity);
	};
	
	public ApplicationContext getOwnerContext() {
		return ownerContext;
	}
	
	public void setApplicationContext(ApplicationContext ctx)
			throws BeansException {
		this.ownerContext = ctx;
	}
	
	public Set<Class<? extends EdgeDescriptor>> getDependClasses() {
		Set<Class<? extends EdgeDescriptor>> returnSet = new HashSet<Class<? extends EdgeDescriptor>>(1);
		returnSet.add(EdgeDescriptor.class);
		return returnSet;
	}

	public boolean dependDescriptor(EdgeDescriptor descriptor) {
		boolean result = false;
		if (isLogDataSourceConfigured() && ClassUtils.isAssignableValue(DataSourceDescriptor.class, descriptor)) {
			result = ObjectUtils.nullSafeEquals(new DataSourceDescriptor(getLogDataSource()), descriptor);
		}
		return result;
	}

	public EdgeDescriptor[] getDescriptorByDepend(EdgeDescriptor descriptor) {
		return new EdgeDescriptor[0];
	}

	public void onApplicationEvent(ApplicationEvent event) {
		if (getOwnerContext() == null) return;
		if (!ObjectUtils.nullSafeEquals(getOwnerContext(), event.getSource())) return;
		if (event instanceof ContextRefreshedEvent) {
			initContext();
		} else if (event instanceof ContextStoppedEvent) {
			finiContext();
		}
	}

	public static class LogConfig {
		
		String dataSourceName = "";
		
		String dataSourceLogLevel = "";
		
		public LogConfig() {}

		public String getDataSourceName() {
			return dataSourceName;
		}

		public void setDataSourceName(String dataSourceName) {
			this.dataSourceName = dataSourceName;
		}

		public String getDataSourceLogLevel() {
			return dataSourceLogLevel;
		}

		public void setDataSourceLogLevel(String dataSourceLogLevel) {
			this.dataSourceLogLevel = dataSourceLogLevel;
		}
	}

}
